package com.wzcl.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.wzcl.app.dao.model.Activity;
import com.wzcl.app.dao.model.AppUser;
import com.wzcl.app.dao.model.Course;
import com.wzcl.app.dao.model.CourseTeacher;
import com.wzcl.app.dao.repository.CourseTeacherRepository;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.common.MyPage;
import com.wzcl.app.model.common.WZCL;
import com.wzcl.app.model.dto.CourseTeacherDto;
import com.wzcl.app.model.vo.BaseVo;
import com.wzcl.app.service.CourseService;
import com.wzcl.app.service.CourseTeacherService;
import com.wzcl.app.service.UserService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Log4j2
@Service
public class CourseTeacherServiceImpl implements CourseTeacherService {

    @Resource
    private CourseTeacherRepository repository;
    @Resource
    private CourseService courseService;
    @Resource
    private UserService userService;

    @Override
    public CourseTeacher addCourseTeacher(CourseTeacherDto courseTeacherDto) {
        CourseTeacher courseTeacher = new CourseTeacher();
        BeanUtils.copyProperties(courseTeacherDto, courseTeacher);
        //校验课程
        Course course = courseService.getAndCheckById(courseTeacher.getCourseId());
        //重复校验
        List<CourseTeacher> courseTeacherList = getCourseTeacherByCourseId(course.getId());
        if (courseTeacherList != null && courseTeacherList.size() > 0) {
            for (CourseTeacher teacher : courseTeacherList) {
                if (teacher.getUserId().equals(courseTeacher.getUserId())) {
                    log.info("CourseTeacher {}：is existed. pass request return this", JSON.toJSONString(teacher));
                    return teacher;
                }
            }
        }
        AppUser teacher = userService.getAndCheckById(courseTeacher.getUserId());
        //校验身份
        if (!WZCL.USER_TYPE.TEACHER.equals(teacher.getType()) && !WZCL.USER_TYPE.ADMIN.equals(teacher.getType())) {
            throw new BusinessException(CodeMsg.USER_STATE_ERROR);
        }
        courseTeacher.setName(teacher.getNickName());
        courseTeacher.setPhone(teacher.getPhone());
        courseTeacher.setHeadIcon(StringUtils.isBlank(teacher.getHeadIcon()) ? BaseVo.DEFAULT_AVATAR_IMAGE : teacher.getHeadIcon());
        return repository.save(courseTeacher);
    }

    @Override
    public CourseTeacher delCourseTeacherById(Integer id) {
        //校验获取
        CourseTeacher courseTeacher = getAndCheckById(id);
        //删除
        log.info("CourseTeacher:{} Physical deletion", JSON.toJSONString(courseTeacher));
        repository.delete(courseTeacher);
        return courseTeacher;
    }

    @Override
    public CourseTeacher updateCourseTeacher(CourseTeacherDto courseTeacherDto) {
        return null;
    }

    @Override
    public CourseTeacher getCourseTeacherById(Integer id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public CourseTeacher getAndCheckById(Integer id) {
        if (id == null) {
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL, "缺少课程教师Id");
        }
        CourseTeacher courseTeacher = getCourseTeacherById(id);
        if (courseTeacher == null) {
            throw new BusinessException(CodeMsg.COURSE_TEACHER_NOT_EXIST);
        }
        return courseTeacher;
    }

    @Override
    public List<CourseTeacher> getCourseTeacherList(CourseTeacherDto courseTeacherDto) {
        return repository.findAll(getSpecification(courseTeacherDto), courseTeacherDto.getSort());
    }

    @Override
    public MyPage<CourseTeacher> getCourseTeacherPage(CourseTeacherDto courseTeacherDto) {
        Page<CourseTeacher> all = repository.findAll(getSpecification(courseTeacherDto), courseTeacherDto.getPageable());
        ArrayList<CourseTeacher> list = new ArrayList<>(all.getContent());
        Collections.reverse(list);
        MyPage<CourseTeacher> myPage = new MyPage<>();
        myPage.setContent(list);
        myPage.setTotalElements(all.getTotalElements());
        return myPage;
    }

    @Override
    public void refreshTeacher(AppUser teacher) {
        String name = teacher.getNickName();
        String headIcon = StringUtils.isBlank(teacher.getHeadIcon()) ? BaseVo.DEFAULT_AVATAR_IMAGE : teacher.getHeadIcon();
        repository.setNameAndHeadIconByUserId(name, headIcon, teacher.getId());
    }

    public List<CourseTeacher> getCourseTeacherByCourseId(Integer id) {
        return repository.findAllByCourseId(id);
    }

    private Specification<CourseTeacher> getSpecification(CourseTeacherDto courseTeacherDto) {
        return new Specification<CourseTeacher>() {
            @Override
            public Predicate toPredicate(Root<CourseTeacher> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (courseTeacherDto.getCourseId() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("courseId"), courseTeacherDto.getCourseId()));
                }
                if (courseTeacherDto.getUserId() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("userId"), courseTeacherDto.getUserId()));
                }
                if (StringUtils.isNotBlank(courseTeacherDto.getName())) {
                    predicates.add(criteriaBuilder.like(root.get("name"), courseTeacherDto.getName()));
                }
                if (courseTeacherDto.getPosition() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("position"), courseTeacherDto.getPosition()));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }
}
